package com.boot.admin.modules.sys.ai.service;

import com.boot.admin.base.R;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * AI语音识别服务（ASR）- 委托给讯飞ASR实现
 *
 * @author 李飞洋
 * @date 2025/9/24
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AiAsrService {

    private final XfyunAsrStreamService xfyunAsrStreamService;

    /**
     * 语音转文字 - 使用讯飞ASR服务
     */
    public R<String> speechToText(MultipartFile audioFile) {
        try {
            if (audioFile == null || audioFile.isEmpty()) {
                return R.NG("音频文件为空");
            }

            log.info("开始调用讯飞ASR语音识别，文件名: {}, 大小: {} bytes",
                    audioFile.getOriginalFilename(), audioFile.getSize());

            // 读取音频文件数据
            byte[] audioData;
            try {
                audioData = audioFile.getBytes();
            } catch (IOException e) {
                log.error("读取音频文件失败", e);
                return R.NG("读取音频文件失败: " + e.getMessage());
            }

            // 使用同步方式调用ASR服务
            AsrSyncResult result = new AsrSyncResult();

            xfyunAsrStreamService.recognizeAudioBatch(audioData, new RealtimeVoiceService.AsrStreamCallback() {
                @Override
                public void onResult(String text, boolean isFinal) {
                    // 对于批量识别，通常只关心最终结果
                    if (isFinal) {
                        result.setText(text);
                        result.setCompleted(true);
                        synchronized (result) {
                            result.notify();
                        }
                    }
                }

                @Override
                public void onError(String error) {
                    result.setError(error);
                    result.setCompleted(true);
                    synchronized (result) {
                        result.notify();
                    }
                }
            });

            // 等待识别完成
            synchronized (result) {
                try {
                    result.wait(30000); // 30秒超时
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return R.NG("语音识别被中断");
                }
            }

            if (!result.isCompleted()) {
                return R.NG("语音识别超时");
            }

            if (result.getError() != null) {
                return R.NG("语音识别失败：" + result.getError());
            }

            String recognizedText = result.getText();
            if (recognizedText == null || recognizedText.trim().isEmpty()) {
                return R.NG("未识别到有效内容");
            }

            log.info("讯飞ASR语音识别结果: {}", recognizedText);
            return R.OK(recognizedText);

        } catch (Exception e) {
            log.error("语音识别失败", e);
            return R.NG("语音识别失败: " + e.getMessage());
        }
    }

    /**
     * 流式语音识别 - 用于实时语音对话
     */
    public void speechToTextStream(byte[] audioData, RealtimeVoiceService.AsrStreamCallback callback) {
        try {
            if (audioData == null || audioData.length == 0) {
                callback.onError("音频数据为空");
                return;
            }

            log.debug("开始调用讯飞ASR流式语音识别，音频大小: {} bytes", audioData.length);

            // 直接委托给讯飞ASR流式服务
            xfyunAsrStreamService.recognizeAudioStream(audioData, callback);

        } catch (Exception e) {
            log.error("流式语音识别失败", e);
            callback.onError("流式语音识别失败: " + e.getMessage());
        }
    }

    /**
     * ASR同步结果辅助类
     */
    private static class AsrSyncResult {
        private String text;
        private String error;
        private boolean completed = false;

        public String getText() { return text; }
        public void setText(String text) { this.text = text; }
        public String getError() { return error; }
        public void setError(String error) { this.error = error; }
        public boolean isCompleted() { return completed; }
        public void setCompleted(boolean completed) { this.completed = completed; }
    }
}